#Updateable is really an abstract class, but there is no such thing in Ruby, because its totally dynamically typed.
#It represents an object that has is continiously updated by 'update_widget' every x seconds
#the 'update_widget' method is not implemented; and the @widget is not initialized. 
#thus the concrete subclasses have totally free reign as to what they want the updateable object to be - 
# all they need to do is create it in the initialize method, and define  'update_widget' behaviour.
class Updateable
	require 'getter.rb'

	#every updateable object needs a string 'getter' function, and an optional update_every x seconds
	def initialize(getter, update_frequency = 10)
		@update_frequency = update_frequency
		@getter = getter
		start_updater
	end
	
	#returns the object that is updated by this updateable
	def widget
		@widget
	end
	
 protected
 	#begins a thread that updates the widget represented by this updater, using the abstract 'update_widget' method
 	def start_updater
 		@updater = Thread.new {
			loop {
				update_widget
				sleep @update_frequency  #wait for the number of seconds specifed before updating again.
			}
		}
 	end
 	
 	#kill the updater thread, usually called just before the GTK widget is destroyed
 	def die  
 		@updater.kill
 	end
end

#Concrete implementation of Updateable - wiget returned is a GTK::Label for containing text.
class UpdateableText < Updateable
	def initialize(getter, update_frequency = 10)
		#this is a text updater, so the element we are updating is going to be a text lablel.
		@widget = Gtk::Label.new getter.get
		@widget.signal_connect("destroy") { self.die } #kill the updater thread when this is destroyed
		super(getter, update_frequency)
	end
 private
 	#called by the updater thread - set the label's text to the result of the getter.
	def update_widget
		#just in case the get function fails(due to connection error etc), we better rescue that. 
		begin
			@widget.text = @getter.get
		rescue
			@widget.text = "error in updater"
		end
		@widget.show
	end
end

#Provides a concrete implementation of a Graph that updates from one or two Getters
class UpdateableGraph < Updateable
	def initialize(getter, getter2 = nil, update_frequency = 10, graph_options = { :colour => 'red'})
		@widget = Graph.new(nil,nil,graph_options)
		@widget.graph.signal_connect("destroy") { self.die } #kill the updater thread when this is destroyed
		@getter2 = getter2
		super(getter, update_frequency)
	end
	
	#override the default widget accessor, so that any class calling it dosent 
	#have to know that you need ".graph()" to get the gtk widget from a graph class.
	#interface abstraction FTW.
	def widget
	  @widget.graph
	end
  
 private
	
	#called by the updater thread - set the label's text to the result of the getter.
	def update_widget

    #since other updaters could be using this getter, give them some time to excute so the data makes its way into history
    #could semaphore it, but it dosent really matter if the graph lags behind.
		sleep 1  
		
		#set the data sets of the graph to the getters' current history.
		@widget.data = @getter.history
	  @widget.data2 = @getter2.history if @getter2
	  
	  #force a refresh of the graph.
		@widget.redraw
	end
	
end
